package com.limi.java8.lambda;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

/**
 * 一、Lambda 表达式的基础语法：Java8中引入了一个新的操作符“->”该操作符称为箭头符或Lambda操作符
 *      箭头操作符将Lambda表达式分成两部分：
 *                                      左侧：Lambda表达式的参数列表
 *                                      右侧：Lambda表达式中所需执行的功能，及Lambda体
 * 语法格式一：无参数，无返回值
 *          ()->System.out.println("Hello Lambda!");
 *
 * 语法格式二：有一个参数，并且无返回值
 *          (x) -> System.out.println(x);
 *
 * 语法格式三：若只有一个参数，小括号可以省略不写
 *          x -> System.out.println(x);
 *
 * 语法格式四：有两个以上的参数，并且Lambda体中有多条语句
 *          Comparator<Integer> com = (x, y) -> {
 *             System.out.println("函数式接口");
 *             return Integer.compare(x, y);
 *          };
 *
 *
 * 语法格式五：若Lambda体中只有一条语句，return和大括号都可以省略不写
 *           Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
 *
 * 语法格式六：Lambda表达式的参数列表的数据类型可以省略不写，因为JVM编译器通过上下文
 * 推断出数据类型，即“类型推断”
 *          (Integer x, Integer y) -> Integer.compare(x, y);
 *
 * 总结（能省则省）：
 *     左右遇一括号省
 *     左侧推断类型省
 *
 * 二、Lambda表达式需要“函数式接口”的支持
 *     函数式接口：接口中只有一个抽象方法的接口，称为函数式接口。可以使用注解@FunctionalInterface修饰
 *                可以检查是否是函数接口。
 *
 *  @author Limi Pan
 * @create 2018-09-16 20:44
 */
public class LambdaSample {

    @Test
    public void test(){
        int num = 888;//jdk1.7前，必须是final

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World!" + num);
            }
        };
        r.run();

        System.out.println("------------------------");

        Runnable r1 = () -> System.out.println("Hello Lambda!");
        r1.run();

    }


    @Test
    public void test2(){
        Consumer consumer = (x) -> System.out.println(x);
        consumer.accept("Limi is handsome!");

    }

    @Test
    public void test3(){
        Consumer consumer = x -> System.out.println(x);//只有一个参数，小括号可以省略不写
        consumer.accept("Limi is handsome!");

    }

    @Test
    public void test4(){
        Comparator<Integer> com = (x, y) -> {
            System.out.println("函数式接口");
            return Integer.compare(x, y);
        };
        Integer integer = com.compare(7, 6);
        System.out.println(integer);
    }

    @Test
    public void test5(){
        Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
        Comparator<String> comparator = (a, b) -> a.compareTo(b);

        System.out.println(com.compare(10, 3));
        System.out.println(comparator.compare("aa", "b"));
    }

    @Test
    public void test6(){
        // 类型推断1
        String[] strs = {"aaa", "bbb", "ccc"};

        // 类型推断2, Java7中不能推断出来
        List<String> list = new ArrayList<>();
    }


    // 需求：对一个数进行运算
    @Test
    public void test7(){
       Integer num = operation(100, (x) -> x * x);
        System.out.println(num);

        System.out.println(operation(200, (y) -> y+200));

    }

    public Integer operation(Integer num, MyFun mf){
        return mf.getValue(num);
    }
}

